/**
 * N8N API 错误类型定义和统一错误处理
 */

export enum N8NErrorType {
  NETWORK_ERROR = 'NETWORK_ERROR',
  AUTH_ERROR = 'AUTH_ERROR', 
  NOT_FOUND = 'NOT_FOUND',
  VALIDATION_ERROR = 'VALIDATION_ERROR',
  PERMISSION_ERROR = 'PERMISSION_ERROR',
  SERVER_ERROR = 'SERVER_ERROR',
  TIMEOUT_ERROR = 'TIMEOUT_ERROR',
  UNKNOWN_ERROR = 'UNKNOWN_ERROR'
}

export class N8NError extends Error {
  public readonly type: N8NErrorType;
  public readonly statusCode?: number;
  public readonly method?: string;
  public readonly url?: string;
  public readonly requestData?: any;
  public readonly responseBody?: string;

  constructor(
    message: string,
    type: N8NErrorType,
    options: {
      statusCode?: number;
      method?: string;
      url?: string;
      requestData?: any;
      responseBody?: string;
      cause?: Error;
    } = {}
  ) {
    super(message);
    this.name = 'N8NError';
    this.type = type;
    this.statusCode = options.statusCode;
    this.method = options.method;
    this.url = options.url;
    this.requestData = options.requestData;
    this.responseBody = options.responseBody;

    if (options.cause) {
      this.cause = options.cause;
    }

    // 确保错误堆栈正确显示
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, N8NError);
    }
  }

  /**
   * 创建格式化的错误信息，用于日志记录
   */
  toLogContext() {
    return {
      type: this.type,
      message: this.message,
      statusCode: this.statusCode,
      method: this.method,
      url: this.url,
      requestData: this.requestData ? JSON.stringify(this.requestData).substring(0, 1000) : undefined,
      responseBody: this.responseBody ? this.responseBody.substring(0, 1000) : undefined,
    };
  }

  /**
   * 创建用户友好的错误消息
   */
  getUserMessage(): string {
    switch (this.type) {
      case N8NErrorType.NETWORK_ERROR:
        return 'N8N服务连接失败，请检查网络连接和服务状态';
      case N8NErrorType.AUTH_ERROR:
        return 'N8N API认证失败，请检查API密钥配置';
      case N8NErrorType.NOT_FOUND:
        return '请求的资源不存在';
      case N8NErrorType.VALIDATION_ERROR:
        return `请求参数验证失败: ${this.message}`;
      case N8NErrorType.PERMISSION_ERROR:
        return '权限不足，无法执行此操作';
      case N8NErrorType.SERVER_ERROR:
        return `N8N服务器内部错误: ${this.message}`;
      case N8NErrorType.TIMEOUT_ERROR:
        return 'N8N API调用超时，请稍后重试';
      default:
        return `N8N API调用失败: ${this.message}`;
    }
  }
}

/**
 * 根据HTTP状态码和错误内容判断错误类型
 */
export function classifyN8NError(
  statusCode: number,
  responseBody: string,
  originalError?: Error
): N8NErrorType {
  // 网络相关错误
  if (originalError) {
    if (originalError.name === 'AbortError' || originalError.message.includes('timeout')) {
      return N8NErrorType.TIMEOUT_ERROR;
    }
    if (originalError.message.includes('fetch') || originalError.message.includes('ECONNREFUSED')) {
      return N8NErrorType.NETWORK_ERROR;
    }
  }

  // HTTP状态码分类
  switch (statusCode) {
    case 401:
      return N8NErrorType.AUTH_ERROR;
    case 403:
      return N8NErrorType.PERMISSION_ERROR;
    case 404:
      return N8NErrorType.NOT_FOUND;
    case 400:
      // 检查响应内容判断是否为验证错误
      if (responseBody.includes('validation') || responseBody.includes('must NOT have additional properties')) {
        return N8NErrorType.VALIDATION_ERROR;
      }
      return N8NErrorType.VALIDATION_ERROR;
    case 405:
      return N8NErrorType.VALIDATION_ERROR; // Method not allowed通常是API使用错误
    case 500:
    case 502:
    case 503:
    case 504:
      return N8NErrorType.SERVER_ERROR;
    default:
      if (statusCode >= 400 && statusCode < 500) {
        return N8NErrorType.VALIDATION_ERROR;
      }
      if (statusCode >= 500) {
        return N8NErrorType.SERVER_ERROR;
      }
      return N8NErrorType.UNKNOWN_ERROR;
  }
}

/**
 * REST请求结果包装器
 * 统一处理成功和失败的情况
 */
export interface RestResult<T = any> {
  success: boolean;
  data?: T;
  error?: N8NError;
}

/**
 * 包装REST API调用，统一错误处理
 */
export async function wrapRestCall<T>(
  apiCall: () => Promise<T>,
  context: {
    operation: string;
    method?: string;
    url?: string;
    requestData?: any;
  }
): Promise<RestResult<T>> {
  try {
    const data = await apiCall();
    return {
      success: true,
      data,
    };
  } catch (error) {
    // 如果已经是N8NError，直接返回
    if (error instanceof N8NError) {
      return {
        success: false,
        error,
      };
    }

    // 处理其他类型的错误
    let n8nError: N8NError;

    if (error instanceof Error) {
      // 检查是否是HTTP错误
      const httpMatch = error.message.match(/^HTTP (\d+): (.+)$/);
      if (httpMatch) {
        const statusCode = parseInt(httpMatch[1]!, 10);
        const responseBody = httpMatch[2]!;
        const errorType = classifyN8NError(statusCode, responseBody, error);
        
        n8nError = new N8NError(
          `${context.operation}失败: ${error.message}`,
          errorType,
          {
            statusCode,
            method: context.method,
            url: context.url,
            requestData: context.requestData,
            responseBody,
            cause: error,
          }
        );
      } else {
        // 其他类型的错误
        const errorType = classifyN8NError(0, '', error);
        n8nError = new N8NError(
          `${context.operation}失败: ${error.message}`,
          errorType,
          {
            method: context.method,
            url: context.url,
            requestData: context.requestData,
            cause: error,
          }
        );
      }
    } else {
      // 非Error对象
      n8nError = new N8NError(
        `${context.operation}失败: ${String(error)}`,
        N8NErrorType.UNKNOWN_ERROR,
        {
          method: context.method,
          url: context.url,
          requestData: context.requestData,
        }
      );
    }

    return {
      success: false,
      error: n8nError,
    };
  }
}
